Home

CloudFormation Challenge

Overview

I was tasked with creating a CloudFormation template that would deploy:

The goal was to build and test the solution until all components deployed successfully.

My Step-by-Step Approach

Step 1: Understanding the Requirements

First, I thoroughly reviewed the requirements to ensure I understood each component needed in the CloudFormation template. I noted that I didn't need to actually access the EC2 instance via SSH, just set up the infrastructure correctly.

Step 2: Creating the CloudFormation Template

I began by creating a YAML file for my CloudFormation template. Using the terminal provided in the environment, I ran:

nano vpc-ec2-template.yaml

Then I wrote the following CloudFormation template:

AWSTemplateFormatVersion: '2010-09-09' Description: 'Template for creating a VPC, Internet Gateway, Security Group, Private Subnet, and EC2 instance' Resources: # Create a VPC MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: MyLabVPC # Create an Internet Gateway MyInternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: MyLabInternetGateway # Attach the Internet Gateway to the VPC AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref MyVPC InternetGatewayId: !Ref MyInternetGateway # Create a Private Subnet MyPrivateSubnet: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC CidrBlock: 10.0.1.0/24 AvailabilityZone: !Select [0, !GetAZs ''] Tags: - Key: Name Value: MyLabPrivateSubnet # Create a Route Table MyRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref MyVPC Tags: - Key: Name Value: MyLabRouteTable # Create a Route to the Internet Gateway MyRoute: Type: AWS::EC2::Route DependsOn: AttachGateway Properties: RouteTableId: !Ref MyRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyInternetGateway # Associate the Route Table with the Subnet MySubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref MyPrivateSubnet RouteTableId: !Ref MyRouteTable # Create a Security Group for SSH MySecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow SSH from anywhere VpcId: !Ref MyVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 Tags: - Key: Name Value: MyLabSecurityGroup # Create an EC2 Instance MyEC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t3.micro SecurityGroupIds: - !Ref MySecurityGroup SubnetId: !Ref MyPrivateSubnet ImageId: ami-0df435f331839b2d6 # Amazon Linux 2 AMI in us-west-2 Tags: - Key: Name Value: MyLabEC2Instance Outputs: VpcId: Description: The ID of the VPC Value: !Ref MyVPC PrivateSubnetId: Description: The ID of the private subnet Value: !Ref MyPrivateSubnet InstanceId: Description: The ID of the EC2 instance Value: !Ref MyEC2Instance

I saved the file using CTRL+O followed by Enter, then exited the editor with CTRL+X.

Step 3: Validating My Template

Before deploying, I validated my template to catch any syntax errors:

aws cloudformation validate-template --template-body file://vpc-ec2-template.yaml

The validation was successful, showing no errors in my template structure.

Step 4: Deploying the CloudFormation Stack

I then deployed my template using the AWS CLI:

aws cloudformation create-stack \ --stack-name ReStartChallengeLabStack \ --template-body file://vpc-ec2-template.yaml \ --capabilities CAPABILITY_IAM

I included the CAPABILITY_IAM flag as a best practice, even though my template didn't include IAM resources.

Step 5: Monitoring the Stack Creation

To track the progress of my stack creation, I ran:

aws cloudformation describe-stacks --stack-name ReStartChallengeLabStack

Initially, the stack status showed CREATE_IN_PROGRESS. I periodically checked the status until it changed to CREATE_COMPLETE.

For more detailed information about the creation events, I used:

aws cloudformation describe-stack-events --stack-name ReStartChallengeLabStack

This helped me see each resource being created in sequence and ensure everything was proceeding correctly.

Step 6: Verifying the Created Resources

Once the stack completed successfully, I verified each resource was created properly:

Checking the VPC:

aws ec2 describe-vpcs --filters "Name=tag:Name,Values=MyLabVPC"

Output confirmed my VPC was created with CIDR block 10.0.0.0/16.

Checking the EC2 instance:

aws ec2 describe-instances --filters "Name=tag:Name,Values=MyLabEC2Instance"

Confirmed my t3.micro instance was running in the correct subnet.

Checking the subnet:

aws ec2 describe-subnets --filters "Name=tag:Name,Values=MyLabPrivateSubnet"

Confirmed the subnet was created with CIDR block 10.0.1.0/24.

Checking the security group:

aws ec2 describe-security-groups --filters "Name=tag:Name,Values=MyLabSecurityGroup"

Verified that the security group had the correct ingress rule allowing SSH from anywhere (port 22).

Step 7: Understanding Key Components in My Template

During this process, I made sure I understood the purpose of each resource in my template:

Step 8: Important Observations

I noted several important aspects of my implementation:

Final Step: Demonstrating

While verifying all components were successfully created I made sure:

It was confirmed that my solution met all the requirements

Conclusion

This process gave me hands-on experience with Infrastructure as Code using AWS CloudFormation. I successfully created a template that deployed a VPC with all the required components including an EC2 instance. The approach of using CloudFormation instead of manually creating resources demonstrated the power of automation in cloud infrastructure deployment.

Through this process, I gained valuable experience with:

This knowledge will be useful for future AWS infrastructure deployments where automation and repeatability are important.

Related Topics